home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / RevRdist Folder / RevRdist / RevRdist src / alias.c next >
Encoding:
C/C++ Source or Header  |  1992-06-26  |  6.4 KB  |  264 lines  |  [TEXT/KAHL]

  1. /*
  2.  * alias.c - routines associated with Finder aliases
  3.  */
  4.  
  5. #include "RevRdist.h"
  6. #include <Aliases.h>
  7. #include <GestaltEqu.h>
  8.  
  9. /*
  10.  * My guess as to the internal structure of an alias
  11.  * Apple reserves the right to change this
  12.  */
  13.  
  14. /*
  15.  * Records after fixed part of alias
  16.  */
  17. struct alias_part
  18. {
  19.     Integer        ap_type;
  20.     Integer        ap_size;
  21. /*    Byte        ap_data[ap_size rounded up to mult of 2]; */
  22. };
  23. typedef    struct alias_part alias_part;
  24.  
  25. /*
  26.  * alias_part_type - deduced values for ap_type
  27.  */
  28. enum    alias_part_type
  29. {
  30.      AL_PNAME = 0                /* parent folder name */
  31.     ,AL_PLIST                    /* parent dirID list */
  32.     ,AL_PATH                    /* full path */
  33.     ,AL_DRIVER = 6                /* driver name (for CD ROM and ?) */
  34.     ,AL_ASHARE = 9                /* volume mount info */
  35. };
  36.  
  37. struct myalias
  38. {
  39.     AliasRecord    al_hdr;            /* Apple header */
  40.     Integer        al_ver;            /* alias version ? */
  41.     Integer        al_unk1;
  42.     Str27        al_volname;        /* volume name */
  43.     unsigned long al_voldate;    /* volume creation date */
  44.     Integer        al_voltype;        /* volume type */
  45.     FSSpec        al_fs;            /* file spec for orig file */
  46.     Longint        al_unk2;        /* directory id ? */
  47.     unsigned long al_unk3;        /* a date of some kind */
  48.     OSType        al_type;        /* file type */
  49.     OSType        al_creator;        /* file creator */
  50.     Integer        al_unk4;
  51.     Integer        al_unk5;
  52.     Integer        al_unk6[8];
  53.     alias_part    al_p[1];        /* first one is always parent dir name */
  54. };
  55. typedef struct myalias myalias;
  56. typedef myalias *myaliasptr, **myaliashandle;
  57.  
  58.  
  59.  
  60. /*
  61.  *=========================================================================
  62.  * update_alias (cn) - update alias information in Finder alias file
  63.  * entry:    cn = cnode for alias file on client
  64.  * returns:    OSErr for system errors
  65.  *            small + integer for internal failures
  66.  *=========================================================================
  67.  */
  68. OSErr
  69. update_alias (cnode_t *cn)
  70. {
  71.     AliasHandle    ah;                    /* handle to new alias */
  72.     myaliasptr    ap;                    /* ptr to original alias */
  73.     alias_part    *app;                /* ptr to alias_part in alias */
  74.     int            c;                    /* char temp */
  75.     int            client;                /* flag set to 0 if cannot be alias
  76.                                      * to file on client */
  77.     OSErr        error;
  78.     alias_part    *fullp;                /* ptr to full path part */
  79.     Handle        h;                    /* handle to original alias */
  80.     int            i, j;                /* temp indexes */
  81.     int            len, flen;            /* temp lengths */
  82.     Longint        lt;                    /* for gestalt() */
  83.     Integer        refnum;                /* file ref num for alias file */
  84.     size_t        size;                /* alias size */
  85.     StringPtr    src, dst;            /* ptrs into full paths */
  86.     CInfoPBRec    ci;
  87.     FSSpec        fs;                    /* file spec for NewAlias */
  88.     Str255        path;                /* new full path */
  89. static int        doAliases = -1;        /* -1->don't know, 0->no, 1->yes */
  90.  
  91.     if (!doAliases)
  92.         return 0;
  93.     if (doAliases < 0)
  94.     {
  95.         lt = 0;
  96.         error = Gestalt (gestaltAliasMgrAttr, <);
  97.         if (error || !(lt & (1<<gestaltAliasMgrPresent)))
  98.         {
  99.             doAliases = 0;
  100.             return 0;
  101.         }
  102.         else
  103.             doAliases = 1;
  104.     }
  105.     Clue0 = "\pupdate_alias";
  106.     Clue1 = "\pHOpenResFile";
  107.     refnum = HOpenResFile (ClientVol, cn->parID, cn->name, fsRdWrPerm);
  108.     if (refnum == -1)
  109.     {
  110.         error = ResError();
  111.         if (error == 0)
  112.             error = fnfErr;
  113.         if (error == fnfErr && (Flags & PF_LISTONLY))
  114.             error = 0;
  115.         return error;
  116.     }
  117.     ah = 0;
  118.     h = Get1Resource (rAliasType, 0);
  119.     while (h)                    /* "while" so can "break" */
  120.     {
  121.         HLock (h);
  122.         error = 1;                /* not our kind of alias */
  123.         ap = *((myaliashandle)h);
  124.         /*
  125.          * Since the internal structure of an alias is not
  126.          * documented, we do some tests to detect changes
  127.          * which might cause our code to fail.
  128.          * We check:
  129.          *    * userType is 0, since that's what the Finder uses
  130.          *    * what we think is the version number is 2
  131.          *    * that there is nothing in the alias past the basic
  132.          *    stuff, since the Finder doesn't use any such
  133.          *    * the first alias_part is for the parent folder name
  134.          */
  135.         size = GetHandleSize(h);
  136.         if (size < sizeof (*ap))
  137.             break;
  138.         if (ap->al_hdr.userType || ap->al_ver != 2
  139.         ||  size != ap->al_hdr.aliasSize)
  140.             break;
  141.         app = ap->al_p;
  142.         if (app->ap_type != AL_PNAME)
  143.             break;
  144.         /*
  145.          * Now, scan through the alias_parts looking for any
  146.          * entries which indicate the alias is not for a file
  147.          * on the client volume.
  148.          * If we find any non-client entries or if we don't
  149.          * find a full path entry, we reject the alias.
  150.          */
  151.         client = 1;
  152.         fullp = 0;
  153.         while (client && app->ap_type >= 0)
  154.         {
  155.             len = app->ap_size;
  156.             flen = len + (len & 1);
  157.             switch (app->ap_type)
  158.             {
  159.             case AL_PNAME:
  160.             case AL_PLIST:
  161.                 break;
  162.             case AL_PATH:
  163.                 fullp = app;
  164.                 break;
  165.             default:
  166.                 client = 0;
  167.                 break;
  168.             }
  169.             app = (alias_part *)((char *)app + sizeof(*app) + flen);
  170.         }
  171.         if (!client)
  172.             break;
  173.         if (!fullp)
  174.             break;
  175.         if ((len = fullp->ap_size) > 255)
  176.             break;
  177.         /*
  178.          * See if the alias target exists as is
  179.          * If so, no need to change alias.
  180.          * We expect target to not exist.  Any other
  181.          * errors are a surprise.
  182.          */
  183.         src = (StringPtr)fullp + sizeof (*fullp) - 1;
  184.         ZERO(ci);
  185.         ci.hFileInfo.ioNamePtr = src;
  186.         ci.hFileInfo.ioVRefNum = ClientVol;
  187.         Clue1 = "\pPBGetCatInfo";
  188.         error = PBGetCatInfo (&ci, false);
  189.         if (error != fnfErr && error != nsvErr && error != dirNFErr)
  190.             break;
  191.         /*
  192.          * Okay, take full path and replace the first part
  193.          * (the volume name) with the client volume name.
  194.          * If this file/folder exists, build a new alias
  195.          * pointing to it.
  196.          */
  197.         COPYPS (ClientVolName, path);
  198.         for (i = 1; i <= len; i++)
  199.             if (src[i] == ':')
  200.                 break;
  201.         dst = path + path[0];
  202.         if (path[0] + (len - i) > 255)
  203.         {
  204.             error = 2;            /* result path too long */
  205.             break;
  206.         }
  207.         for ( ; i <= len; i++)
  208.         {
  209.             *++dst = c = src[i];
  210.             if (c == ':' && i < len)
  211.                 j = i;            /* j indexes start of last part */
  212.         }
  213.         path[0] = dst - path;
  214.         ZERO(ci);
  215.         ci.hFileInfo.ioNamePtr = path;
  216.         ci.hFileInfo.ioVRefNum = ClientVol;
  217.         error = PBGetCatInfo (&ci, false);
  218.         if (error)
  219.         {
  220.             if (error == fnfErr || error == dirNFErr)
  221.                 error = 3;
  222.             break;
  223.         }
  224.         fs.vRefNum = ClientVol;
  225.         fs.parID = ci.hFileInfo.ioFlParID;
  226.         flen = len - j;
  227.         BlockMove (src + j + 1, fs.name + 1, flen);
  228.         fs.name[0] = flen;
  229.         Clue1 = "\pNewAlias";
  230.         error = NewAlias (nil, &fs, &ah);
  231.         if (error == 0 && ah == 0)
  232.             error = 4;
  233.         if (error)
  234.             break;
  235.         len = (*ah)->aliasSize;
  236.         if (Flags & PF_VERBOSE)
  237.         {
  238.             notice (L_ALIAS, fs.name, nil);
  239.         }
  240.         if (!(Flags & PF_LISTONLY))
  241.         {
  242.             HUnlock (h);
  243.             SetHandleSize (h, len);
  244.             error = MemError();
  245.             if (error)
  246.                 break;
  247.             HLock (h);
  248.             BlockMove ((Ptr)(*ah), (*h), len);
  249.             ChangedResource (h);
  250.             if (error = ResError())
  251.                 break;
  252.         }
  253.         break;
  254.     }
  255.     if (h)
  256.     {
  257.         HUnlock (h);
  258.         ReleaseResource (h);
  259.     }
  260.     if (ah)
  261.         DisposHandle ((Handle)ah);
  262.     (void) CloseResFile (refnum);
  263.     return error;
  264. }